
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h"
#include "esp_log.h"
#include "esp_err.h"

#define EXAMPLE_MAX_CHAR_SIZE    64

static const char *TAG = "sdcard_example";

#define BSP_SD_CMD 48
#define BSP_SD_CLK 47
#define BSP_SD_D0  21

static esp_err_t s_example_write_file(const char *path, char *data);

static esp_err_t s_example_read_file(const char *path);

static esp_err_t bsp_read_wav(const char *path);

#define MOUNT_POINT "/sdcard"

void bsp_sdcard_init(){
    esp_err_t ret;

    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = true,
        .max_files = 5,
        .allocation_unit_size = 16 * 1024
    };
    sdmmc_card_t *card;
    const char mount_point[] = MOUNT_POINT;
    ESP_LOGI(TAG, "Initializing SD card");
    ESP_LOGI(TAG, "Using SDMMC peripheral");

    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();


    slot_config.width = 1;
    slot_config.clk = BSP_SD_CLK;
    slot_config.cmd = BSP_SD_CMD;
    slot_config.d0 = BSP_SD_D0;

    slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;

    ESP_LOGI(TAG, "Mounting filesystem");
    ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);

    if (ret != ESP_OK) {
        if (ret == ESP_FAIL) {
            ESP_LOGE(TAG, "SD加载失败");
        } else {
            ESP_LOGE(TAG, "Failed to initialize the card (%s).", esp_err_to_name(ret));
        }
        return;
    }
    ESP_LOGI(TAG, "Filesystem mounted");

    // Card has been initialized, print its properties
    sdmmc_card_print_info(stdout, card);

    const char *file_hello = MOUNT_POINT"/hello.txt";
    char data[EXAMPLE_MAX_CHAR_SIZE];
    snprintf(data, EXAMPLE_MAX_CHAR_SIZE, "%s %s!\n", "Hello", card->cid.name);
    ret = s_example_write_file(file_hello, data);
    if (ret != ESP_OK) {
        return;
    }
    
    ret = s_example_read_file(file_hello);
    if (ret != ESP_OK) {
        return;
    }
}

void example_sdcard_test(){
    bsp_sdcard_init();

    bsp_read_wav(MOUNT_POINT"/muyu.wav");

}
#include "i2s/format_wav.h"
static esp_err_t bsp_read_wav(const char *path){
    ESP_LOGI(TAG, "Reading file %s", path);
    FILE *f = fopen(path, "r");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return ESP_FAIL;
    }
    
    wav_header_t  wav_header;
    fread(&wav_header.descriptor_chunk,sizeof(wav_header.descriptor_chunk),1,f);    
    fread(&wav_header.fmt_chunk,sizeof(wav_header.fmt_chunk),1,f);    

    printf("文件类型: %.4s\r\n", wav_header.descriptor_chunk.chunk_id);
    printf("文件大小: %ld\r\n", wav_header.descriptor_chunk.chunk_size);

    // 读取fmt块
    
    printf("音频格式: %d\n", wav_header.fmt_chunk.audio_format);
    printf("通道数: %d\n", wav_header.fmt_chunk.num_of_channels);
    printf("采样率: %ld\n", wav_header.fmt_chunk.sample_rate);
    printf("位深: %d\n", wav_header.fmt_chunk.bits_per_sample);


    //uint8_t data[EXAMPLE_MAX_CHAR_SIZE];
    
    fclose(f);


    return ESP_OK;
}


static esp_err_t s_example_write_file(const char *path, char *data)
{
    ESP_LOGI(TAG, "Opening file %s", path);
    FILE *f = fopen(path, "w");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return ESP_FAIL;
    }
    fprintf(f, data);
    fclose(f);
    ESP_LOGI(TAG, "File written");

    return ESP_OK;
}


static esp_err_t s_example_read_file(const char *path)
{
    ESP_LOGI(TAG, "Reading file %s", path);
    FILE *f = fopen(path, "r");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return ESP_FAIL;
    }
    
    char line[EXAMPLE_MAX_CHAR_SIZE];
    fgets(line, sizeof(line), f);
    fclose(f);

    // strip newline
    char *pos = strchr(line, '\n');
    if (pos) {
        *pos = '\0';
    }
    ESP_LOGI(TAG, "Read from file: '%s'", line);

    return ESP_OK;
}
